package com.zbkj.crmeb.chant.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.utils.CrmebUtil;
import com.utils.DateUtil;
import com.utils.vo.dateLimitUtilVo;
import com.zbkj.crmeb.chant.dao.ChannelPartitionCouponDao;
import com.zbkj.crmeb.chant.model.ChannelPartitionCoupon;
import com.zbkj.crmeb.chant.model.ChannelPartitionCouponProduct;
import com.zbkj.crmeb.chant.model.ChannelPartitionInfo;
import com.zbkj.crmeb.chant.model.ChannelPartitionUser;
import com.zbkj.crmeb.chant.request.ChannelPartitionCouponRequest;
import com.zbkj.crmeb.chant.response.ChannelPartitionCouponResponse;
import com.zbkj.crmeb.chant.response.ChannelPartitionInfoResponse;
import com.zbkj.crmeb.chant.response.ChannelPartitionUserResponse;
import com.zbkj.crmeb.chant.service.ChannelPartitionCouponProductService;
import com.zbkj.crmeb.chant.service.ChannelPartitionCouponService;
import com.zbkj.crmeb.chant.service.ChannelPartitionInfoService;
import com.zbkj.crmeb.chant.service.ChannelPartitionUserService;
import com.zbkj.crmeb.enums.CouponUserTypeEnum;
import com.zbkj.crmeb.marketing.model.StoreCoupon;
import com.zbkj.crmeb.marketing.service.StoreCouponService;
import com.zbkj.crmeb.marketing.service.StoreCouponUserService;
import com.zbkj.crmeb.store.model.StoreProduct;
import com.zbkj.crmeb.store.model.StoreProductCoupon;
import com.zbkj.crmeb.store.service.StoreProductCouponService;
import com.zbkj.crmeb.store.service.StoreProductService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.response.UserResponse;
import com.zbkj.crmeb.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ChannelPartitionCouponServiceImpl extends ServiceImpl<ChannelPartitionCouponDao, ChannelPartitionCoupon> implements ChannelPartitionCouponService {

    @Autowired
    private ChannelPartitionCouponProductService channelPartitionCouponProductService;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private Redisson redisson;
    @Autowired
    private ChannelPartitionInfoService channelPartitionInfoService;
    @Autowired
    private UserService userService;
    @Autowired
    private ChannelPartitionUserService channelPartitionUserService;
    @Autowired
    private StoreCouponService storeCouponService;
    @Autowired
    private StoreProductCouponService storeProductCouponService;

    @Override
    public Boolean saveOrUpdateInfo(ChannelPartitionCouponRequest request, Integer merId) {
        ChannelPartitionCoupon channelPartitionCoupon = new ChannelPartitionCoupon();
        BeanUtils.copyProperties(request, channelPartitionCoupon);
        dateLimitUtilVo dateLimit = DateUtil.getDateLimit(request.getActivityTime());
        channelPartitionCoupon.setStartTime(DateUtil.strToDate(dateLimit.getStartTime(), Constants.DATE_FORMAT));
        channelPartitionCoupon.setEndTime(DateUtil.strToDate(dateLimit.getEndTime(), Constants.DATE_FORMAT));
        channelPartitionCoupon.setMerId(merId);
        channelPartitionCoupon.setStock(request.getPartitionTotalNumber());
        boolean saveOrUpdate = this.saveOrUpdate(channelPartitionCoupon);
        if (!saveOrUpdate) {
            return false;
        }
        if (request.getUseType() == 2) {
            channelPartitionCouponProductService.remove(Wrappers.<ChannelPartitionCouponProduct>lambdaQuery().eq(ChannelPartitionCouponProduct::getPartitionId, channelPartitionCoupon.getId()));
            List<ChannelPartitionCouponProduct> channelPartitionCouponProducts = new ArrayList<>();
            for (Integer productId : request.getProductIds()) {
                ChannelPartitionCouponProduct channelPartitionCouponProduct = new ChannelPartitionCouponProduct();
                channelPartitionCouponProduct.setPartitionId(channelPartitionCoupon.getId());
                channelPartitionCouponProduct.setProductId(productId);
                channelPartitionCouponProducts.add(channelPartitionCouponProduct);
            }
            channelPartitionCouponProductService.saveBatch(channelPartitionCouponProducts);
        }
        return true;
    }

    @Override
    public Boolean earlyTerminationActivity(Integer id) {
        return this.update(Wrappers.<ChannelPartitionCoupon>lambdaUpdate().eq(ChannelPartitionCoupon::getId, id)
                .set(ChannelPartitionCoupon::getEndTime, new Date()));
    }

    @Override
    public Boolean delPartition(Integer id) {
        boolean remove = this.update(Wrappers.<ChannelPartitionCoupon>lambdaUpdate().eq(ChannelPartitionCoupon::getId, id).set(ChannelPartitionCoupon::getIsDel, true));
        boolean removeProduct = channelPartitionCouponProductService.remove(Wrappers.<ChannelPartitionCouponProduct>lambdaQuery().eq(ChannelPartitionCouponProduct::getPartitionId, id));
        return removeProduct && remove;
    }

    @Override
    public CommonPage<ChannelPartitionCouponResponse> getList(ChannelPartitionCouponRequest request, PageParamRequest pageParamRequest, Integer merId) {
        LambdaQueryWrapper<ChannelPartitionCoupon> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChannelPartitionCoupon::getMerId, merId);
        queryWrapper.eq(ChannelPartitionCoupon::getIsDel, false);
        if (StringUtils.isNotBlank(request.getPartitionName())) {
            queryWrapper.like(ChannelPartitionCoupon::getPartitionName, request.getPartitionName());
        }
        if (Objects.nonNull(request.getStatus())) {
            switch (request.getStatus()) {
                case 1:
                    queryWrapper.gt(ChannelPartitionCoupon::getStartTime, new Date());
                    break;
                case 2:
                    queryWrapper.gt(ChannelPartitionCoupon::getEndTime, new Date())
                            .lt(ChannelPartitionCoupon::getStartTime, new Date());
                    break;
                case 3:
                    queryWrapper.lt(ChannelPartitionCoupon::getEndTime, new Date());
                    break;
                default:
                    break;
            }
        }
        Page<Object> page = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        List<ChannelPartitionCoupon> channelPartitionCoupons = this.list(queryWrapper);
        List<ChannelPartitionCouponResponse> responses = new ArrayList<>();
        for (ChannelPartitionCoupon channelPartitionCoupon : channelPartitionCoupons) {
            ChannelPartitionCouponResponse response = new ChannelPartitionCouponResponse();
            BeanUtils.copyProperties(channelPartitionCoupon, response);
            // 未开始
            if (channelPartitionCoupon.getStartTime().after(new Date())) {
                response.setStatus(1);
                // 已结束
            } else if (channelPartitionCoupon.getEndTime().before(new Date())) {
                response.setStatus(3);
            } else {
                response.setStatus(2);
            }
            responses.add(response);
        }

        return CommonPage.restPage(CommonPage.copyPageInfo(page, responses));
    }

    @Override
    public ChannelPartitionCouponResponse getInfo(Integer id, Integer merId) {
        ChannelPartitionCouponResponse response = new ChannelPartitionCouponResponse();
        ChannelPartitionCoupon channelPartitionCoupon = this.getOne(Wrappers.<ChannelPartitionCoupon>lambdaQuery().eq(ChannelPartitionCoupon::getId, id).eq(ChannelPartitionCoupon::getMerId, merId).last("limit 1"));
        if (Objects.isNull(channelPartitionCoupon)) {
            return response;
        }
        BeanUtils.copyProperties(channelPartitionCoupon, response);
        response.setStartTime(DateUtil.dateToStr(channelPartitionCoupon.getStartTime(), Constants.DATE_FORMAT));
        response.setEndTime(DateUtil.dateToStr(channelPartitionCoupon.getEndTime(), Constants.DATE_FORMAT));
        if (channelPartitionCoupon.getUseType() == 2) {
            List<ChannelPartitionCouponProduct> channelPartitionCouponProducts = channelPartitionCouponProductService.list(Wrappers.<ChannelPartitionCouponProduct>lambdaQuery().eq(ChannelPartitionCouponProduct::getPartitionId, id));
            List<Integer> productIds = channelPartitionCouponProducts.stream().map(ChannelPartitionCouponProduct::getProductId).collect(Collectors.toList());
            List<StoreProduct> storeProducts = storeProductService.getListInIds(productIds);
            response.setStoreProducts(storeProducts);
        }
        return response;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public Boolean receivePartitionCoupon(Integer partitionId) {
        String lockKey = "partition_id:" + partitionId;
        RLock rLock = redisson.getLock(lockKey);
        try {
            rLock.lock();
            Integer uid = userService.getUserIdException();
            User user = userService.getById(uid);
            if (Objects.isNull(user)) {
                throw new CrmebException("用户不存在！");
            }
            ChannelPartitionCoupon channelPartitionCoupon = this.getById(partitionId);
            if (Objects.isNull(channelPartitionCoupon)) {
                log.info("--------------- 用户id: {}, 瓜分券id: {}, 瓜分券不存在！ ---------------", uid, partitionId);
                throw new CrmebException("瓜分券不存在！");
            }
            if (channelPartitionCoupon.getStock() == 0) {
                log.info("--------------- 用户id: {}, 瓜分券id: {}, 瓜分券数量不足！ ---------------", uid, partitionId);
                throw new CrmebException("瓜分券已被抢完~");
            }
            if (channelPartitionCoupon.getStartTime().after(new Date())) {
                log.info("--------------- 用户id: {}, 瓜分券id: {}, 瓜分券活动暂未开始！ ---------------", uid, partitionId);
                throw new CrmebException("瓜分券活动暂未开始!");
            }
            if (channelPartitionCoupon.getEndTime().before(new Date())) {
                log.info("--------------- 用户id: {}, 瓜分券id: {}, 瓜分券活动已结束！ ---------------", uid, partitionId);
                throw new CrmebException("瓜分券活动已结束！");
            }
            if (channelPartitionCoupon.getIsDel()) {
                log.info("--------------- 用户id: {}, 瓜分券id: {}, 瓜分券已删除！ ---------------", uid, partitionId);
                throw new CrmebException("瓜分券已失效！");
            }
            if (!Objects.equals(channelPartitionCoupon.getMerId(), user.getMerId())) {
                log.info("--------------- 用户id: {}, 瓜分券id: {}, 瓜分券状态不符！ ---------------", uid, partitionId);
                throw new CrmebException("瓜分券状态不符！");
            }
            // 瓜分券限制次数
            if (channelPartitionCoupon.getUseTime() == 2) {
                // 用户参与当前瓜分券次数
                Integer userPartitionTime = channelPartitionUserService.getUserPartitionTime(uid, partitionId);
                if (Objects.equals(userPartitionTime, channelPartitionCoupon.getTimeCondition())) {
                    throw new CrmebException(StrUtil.format("当前优惠券限制瓜分{}次，您已达瓜分上限！", channelPartitionCoupon.getTimeCondition()));
                }
            }
            // 检查是否参与当前瓜分券
            List<ChannelPartitionInfo> userInPartitionInfos = channelPartitionInfoService.getUserInPartitionInfo(uid);
            if (CollectionUtils.isNotEmpty(userInPartitionInfos)) {
                List<Integer> partitionIds = userInPartitionInfos.stream().map(ChannelPartitionInfo::getPartitionId).collect(Collectors.toList());
                if (partitionIds.contains(partitionId)) {
                    throw new CrmebException("您已参与当前瓜分活动，请勿重复领取");
                }
            }
            // 满足领取条件，信息进行保存
            ChannelPartitionInfo info = new ChannelPartitionInfo();
            info.setPartitionId(partitionId);
            info.setPartitionNumber(channelPartitionCoupon.getPersonNumber());
            info.setUids(String.valueOf(uid));
            info.setStatus(false);
            info.setLastPerson(channelPartitionCoupon.getPersonNumber());
            info.setLastMoney(channelPartitionCoupon.getPartitionMoney());
            channelPartitionInfoService.save(info);
            // 扣除瓜分券库存
            Boolean stock = updatePartitionCouponStock(channelPartitionCoupon.getId(), channelPartitionCoupon.getStock() - 1);
            if (!stock) {
                throw new CrmebException("瓜分券已被抢完~");
            }
        } finally {
            if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
        return true;
    }

    @Override
    public ChannelPartitionInfoResponse getPartitionInfo(Integer id, Integer partitionId) {
        Integer userId = userService.getUserIdException();
        ChannelPartitionInfoResponse response = new ChannelPartitionInfoResponse();
        // id为空，不是通过分享进入界面，查询当前用户是否有参与的瓜分券
        if (Objects.isNull(id)) {
            // 当前用户所在瓜分活动
            List<ChannelPartitionInfo> channelPartitionInfos = channelPartitionInfoService.getUserInPartitionInfo(userId);
            // 当前准备发起瓜分的瓜分券活动
            ChannelPartitionCoupon channelPartitionCoupon = this.getById(partitionId);
            if (Objects.isNull(channelPartitionCoupon)) {
                throw new CrmebException("瓜分券信息获取失败，请联系商家！");
            }
            response.setPartitionId(partitionId);
            response.setPartitionMoney(channelPartitionCoupon.getPartitionMoney());
            response.setPersonNumber(channelPartitionCoupon.getPersonNumber());
            // 不存在瓜分活动，返回空让前端处理
            if (CollectionUtils.isEmpty(channelPartitionInfos)) {
                return response;
            }
            // 用户所在瓜分券id
            List<Integer> partitionIds = channelPartitionInfos.stream().map(ChannelPartitionInfo::getPartitionId).collect(Collectors.toList());
            // 用户不在当前瓜分券活动
            if (!partitionIds.contains(partitionId)) {
                return response;
            }
            Map<Integer, ChannelPartitionInfo> channelPartitionInfoMap = channelPartitionInfos.stream().collect(Collectors.toMap(ChannelPartitionInfo::getPartitionId, Function.identity()));
            ChannelPartitionInfo channelPartitionInfo = channelPartitionInfoMap.get(partitionId);
            BeanUtils.copyProperties(channelPartitionInfo, response);
            response.setCreateTime(DateUtil.dateToStr(channelPartitionInfo.getCreateTime(), Constants.DATE_FORMAT));
            List<Integer> uids = CrmebUtil.stringToArray(channelPartitionInfo.getUids());
            LinkedList<UserResponse> userResponses = getUserResponse(uids);
            response.setUsers(userResponses);
            // 满足瓜分条件，判断用户是否点击过开红包
            if (channelPartitionInfo.getStatus()) {
                response.setIsPartition(channelPartitionUserService.checkUserPartitionStatus(userId, channelPartitionInfo.getPartitionId()));
            }
            return response;
        }
        // 通过分享界面进入瓜分券界面
        String lockKey = "partition_info_id:" + id;
        RLock rLock = redisson.getLock(lockKey);
        try {
            if (!rLock.tryLock()) {
                throw new CrmebException("请重试！");
            }
            ChannelPartitionInfo info = channelPartitionInfoService.getById(id);
            // 瓜分活动不存在
            if (Objects.isNull(info)) {
                return response;
            }
            if (info.getStatus()) {
                throw new CrmebException("好友人数已足够");
            }
            List<Integer> uids = CrmebUtil.stringToArray(info.getUids());
            // 自己从自己分享的界面进入
            if (uids.contains(userId)) {
                BeanUtils.copyProperties(info, response);
                LinkedList<UserResponse> userResponse = getUserResponse(uids);
                response.setUsers(userResponse);
                response.setCreateTime(DateUtil.dateToStr(info.getCreateTime(), Constants.DATE_FORMAT));
                // 满足瓜分条件，判断用户是否点击过开红包
                if (info.getStatus()) {
                    response.setIsPartition(channelPartitionUserService.checkUserPartitionStatus(userId, info.getPartitionId()));
                }
                return response;
            }
            uids.add(userId);
            info.setUids(uids.stream().map(String::valueOf).collect(Collectors.joining(",")));
            if (uids.size() == info.getPartitionNumber()) {
                info.setStatus(true);
            }
            channelPartitionInfoService.updateById(info);
            BeanUtils.copyProperties(info, response);
            LinkedList<UserResponse> userResponse = getUserResponse(uids);
            response.setUsers(userResponse);
            response.setCreateTime(DateUtil.dateToStr(info.getCreateTime(), Constants.DATE_FORMAT));
            return response;
        } finally {
            if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
            }
        }
    }

    @Override
    public ChannelPartitionUserResponse partitionOpen(Integer partitionId, Integer merId) {
        ChannelPartitionUserResponse response = new ChannelPartitionUserResponse();
        // 当前开红包用户
        Integer userId = userService.getUserIdException();
        ChannelPartitionUser partitionUser = channelPartitionUserService.getPartitionUser(userId, partitionId);
        // 不为空，之前已打开，返回信息
        if (Objects.nonNull(partitionUser)) {
            BeanUtils.copyProperties(partitionUser, response);
        } else {
            // 查询瓜分券
            ChannelPartitionCoupon channelPartitionCoupon = this.getById(partitionId);
            // 用户所在瓜分活动
            List<ChannelPartitionInfo> userInPartitionInfos = channelPartitionInfoService.getUserInPartitionInfo(userId);
            List<Integer> partitionIds = userInPartitionInfos.stream().map(ChannelPartitionInfo::getPartitionId).collect(Collectors.toList());
            // 没有匹配上
            if (!partitionIds.contains(partitionId)) {
                log.info("--------------- 瓜分券开红包失败：用户id：{}, 瓜分券id：{}, 用户所属瓜分券id：{} ---------------", userId, partitionId, partitionIds);
                throw new CrmebException("请稍后重试！");
            }
            Map<Integer, ChannelPartitionInfo> channelPartitionInfoMap = userInPartitionInfos.stream().collect(Collectors.toMap(ChannelPartitionInfo::getPartitionId, Function.identity()));
            ChannelPartitionInfo userInPartitionInfo = channelPartitionInfoMap.get(partitionId);
            // 通过瓜分券设置方式瓜分到的金额
            BigDecimal partitionMoney;
            // 均分
            if (channelPartitionCoupon.getPartitionType() == 1) {
                BigDecimal partitionTotalMoney = channelPartitionCoupon.getPartitionMoney();
                Integer personNumber = channelPartitionCoupon.getPersonNumber();
                partitionMoney = partitionTotalMoney.divide(BigDecimal.valueOf(personNumber), 2, RoundingMode.DOWN);
            // 拼手气
            } else {
                // 瓜分总金额
                BigDecimal partitionTotalMoney = userInPartitionInfo.getLastMoney();
                // 仅剩一人瓜分
                if (userInPartitionInfo.getLastPerson() == 1) {
                    partitionMoney = partitionTotalMoney;
                } else {
                    Random random = new Random();
                    BigDecimal subtract = partitionTotalMoney.subtract(BigDecimal.ONE);
                    partitionMoney = new BigDecimal(random.nextInt(subtract.intValueExact()) + 1);
                }
            }
            // 发放优惠券
            bindCoupon(merId, channelPartitionCoupon, partitionMoney, userId);
            // 更新人数与剩余金额
            userInPartitionInfo.setLastPerson(userInPartitionInfo.getLastPerson() - 1);
            userInPartitionInfo.setLastMoney(userInPartitionInfo.getLastMoney().subtract(partitionMoney));
            channelPartitionInfoService.updateById(userInPartitionInfo);
            // 保存瓜分信息
            channelPartitionUserService.saveUserPartition(userId, partitionId, channelPartitionCoupon.getMoneyCondition(), partitionMoney, channelPartitionCoupon.getUseType());
            response.setPartitionMoney(partitionMoney);
            response.setUseCondition(channelPartitionCoupon.getMoneyCondition());
            response.setUseType(channelPartitionCoupon.getUseType());
        }
        getUserResponses(partitionId, userId, response);

        return response;
    }

    @Override
    public void cancelBySystem() {
        LambdaQueryWrapper<ChannelPartitionInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChannelPartitionInfo::getStatus, 0);
        List<ChannelPartitionInfo> channelPartitionInfos = channelPartitionInfoService.list(queryWrapper);
        for (ChannelPartitionInfo channelPartitionInfo : channelPartitionInfos) {
            // 瓜分信息创建时间
            LocalDateTime createTime = channelPartitionInfo.getCreateTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
            // 超时未成功
            if (createTime.plusDays(1).isBefore(LocalDateTime.now())) {
                channelPartitionInfoService.removeById(channelPartitionInfo.getId());
                ChannelPartitionCoupon channelPartitionCoupon = this.getById(channelPartitionInfo.getPartitionId());
                updatePartitionCouponStock(channelPartitionCoupon.getId(), channelPartitionCoupon.getStock() + 1);
            }
        }
    }

    /**
     * 功能描述: 扣除库存
     * @Param: [id, stock]
     * @Return: java.lang.Boolean
     * @Author: wangzh
     * @Date: 2023/6/12 14:31
     */
    private Boolean updatePartitionCouponStock(Integer id, Integer stock) {
        return this.update(Wrappers.<ChannelPartitionCoupon>lambdaUpdate().eq(ChannelPartitionCoupon::getId, id)
                .set(ChannelPartitionCoupon::getStock, stock));
    }

    /**
     * 功能描述: 获取用户列表
     * @Param: [uids]
     * @Return: java.util.LinkedList<com.zbkj.crmeb.user.response.UserResponse>
     * @Author: wangzh
     * @Date: 2023/6/12 15:26
     */
    private LinkedList<UserResponse> getUserResponse(List<Integer> uids) {
        HashMap<Integer, User> userHashMap = userService.getMapListInUid(uids);
        LinkedList<UserResponse> userResponses = new LinkedList<>();
        for (Integer uid : uids) {
            User user = userHashMap.get(uid);
            UserResponse response = new UserResponse();
            BeanUtils.copyProperties(user, response);
            userResponses.add(response);
        }
        return userResponses;
    }

    /**
     * 功能描述: 发送优惠券
     * @Param: []
     * @Return: void
     * @Author: wangzh
     * @Date: 2023/6/13 15:16
     */
    private void bindCoupon(Integer merId, ChannelPartitionCoupon channelPartitionCoupon, BigDecimal partitionMoney, Integer userId) {
        StoreCoupon storeCoupon = new StoreCoupon();
        storeCoupon.setMerId(merId);
        storeCoupon.setName("瓜分券瓜分");
        storeCoupon.setStatus(false);
        storeCoupon.setUseType(channelPartitionCoupon.getUseType());
        storeCoupon.setMoney(partitionMoney);
        storeCoupon.setMinPrice(channelPartitionCoupon.getUseCondition() ? channelPartitionCoupon.getMoneyCondition() : BigDecimal.ZERO);
        storeCoupon.setTotal(1);
        storeCoupon.setLastTotal(1);
        storeCoupon.setReceiveStartTime(new Date());
        storeCoupon.setReceiveEndTime(DateUtil.addDay(new Date(), 1));
        storeCoupon.setIsFixedTime(false);
        storeCoupon.setDay(channelPartitionCoupon.getUseDay());
        storeCoupon.setLastDay(0);
        storeCoupon.setLimitTotal(1);
        storeCoupon.setType(2);
        storeCoupon.setCrowd(1);
        storeCoupon.setIsDel(false);
        storeCoupon.setReleaseType(1);
        storeCoupon.setIsPartition(true);
        boolean save = storeCouponService.save(storeCoupon);
        if (save && channelPartitionCoupon.getUseType() == 2) {
            List<ChannelPartitionCouponProduct> channelPartitionCouponProducts = channelPartitionCouponProductService.list(Wrappers.<ChannelPartitionCouponProduct>lambdaQuery()
                    .eq(ChannelPartitionCouponProduct::getPartitionId, channelPartitionCoupon.getId()));
            List<StoreProductCoupon> storeProductCoupons = new ArrayList<>();
            channelPartitionCouponProducts.stream().forEach(e -> {
                StoreProductCoupon storeProductCoupon = new StoreProductCoupon();
                storeProductCoupon.setIssueCouponId(storeCoupon.getId());
                storeProductCoupon.setProductId(e.getProductId());
                storeProductCoupons.add(storeProductCoupon);
            });
            storeProductCouponService.saveBatch(storeProductCoupons);
        }
        storeCouponService.bindCouponByUser(Collections.singletonList(userId), storeCoupon.getId(), CouponUserTypeEnum.AUTO);
    }

    /**
     * 功能描述: 设置好友运气列表
     * @Param: [partitionId, userId, response]
     * @Return: void
     * @Author: wangzh
     * @Date: 2023/6/13 16:21
     */
    private void getUserResponses(Integer partitionId, Integer userId, ChannelPartitionUserResponse response) {
        // 好友手气
        List<ChannelPartitionUser> channelPartitionUsers = channelPartitionUserService.list(Wrappers.<ChannelPartitionUser>lambdaQuery().eq(ChannelPartitionUser::getPartitionId, partitionId));
        // 过滤自己
        channelPartitionUsers = channelPartitionUsers.stream().filter(e -> !Objects.equals(e.getUid(), userId)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(channelPartitionUsers)) {
            response.setUserResponses(null);
        } else {
            List<ChannelPartitionUserResponse> userResponses = new ArrayList<>();
            List<Integer> uids = channelPartitionUsers.stream().map(ChannelPartitionUser::getUid).collect(Collectors.toList());
            HashMap<Integer, User> userHashMap = userService.getMapListInUid(uids);
            for (ChannelPartitionUser channelPartitionUser : channelPartitionUsers) {
                ChannelPartitionUserResponse userResponse = new ChannelPartitionUserResponse();
                BeanUtils.copyProperties(channelPartitionUser, userResponse);
                User user = userHashMap.get(channelPartitionUser.getUid());
                userResponse.setNickname(user.getNickname());
                userResponse.setAvatar(user.getAvatar());
                userResponses.add(userResponse);
            }
            response.setUserResponses(userResponses);
        }
    }
}
